package BandB.Tool.GPhoneManager.Widget;

import BandB.Tool.GPhoneManager.ConfigManager;
import BandB.Tool.GPhoneManager.R;
import BandB.Tool.GPhoneManager.AppManager.Settings;
import BandB.Tool.GPhoneManager.Widget.AndroidBrightnessControl.AndroidBrightnessControl;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.net.wifi.WifiManager;
import android.provider.Settings.System;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;

public class TogglesWidget extends AppWidgetProvider implements
		AirplaneListener, WifiListener {

	private static final String TAG = TogglesWidget.class.getSimpleName();
	private static final String ACTION_AIRPLANE_CHANGED = "airplane_mode_changed";
	public static final String ACTION_SILENT_CHANGED = "silent_mode_changed";
	private static final String ACTION_WIFI_CHANGED = "wifi_mode_changed";

	// The following two variables customized will be used to determine whether
	// change mode(airplane, silent, wi_fi) forced
	private static final String MSG_MODE_NO_CHANGE = "msg_no_change";
	private static final boolean NO_CHANGE_VALUE = true;
	private static final String IS_CUSTOMIZED = "is_customized";
	private static final boolean CUSTOMIZED = true;
	private static final boolean NO_CUSTOMIZED = false;

	@Override
	public void onAirplaneModeChanged(int turn, RemoteViews views) {
		// TODO Auto-generated method stub
		if (turn == AIRPLANE_TURN_ON) {
			views.setImageViewResource(R.id.btnAirplane, R.drawable.airplane3);
		} else {
			views.setImageViewResource(R.id.btnAirplane, R.drawable.airplane);
		}
	}

	@Override
	public void onWifiStatusChanged(int turn, RemoteViews views) {
		// TODO Auto-generated method stub
		if (turn == WIFI_TURN_ON) {
			views.setImageViewResource(R.id.btnWifi, R.drawable.wifi3);
		} else {
			views.setImageViewResource(R.id.btnWifi, R.drawable.wifi);
		}
	}

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		// TODO Auto-generated method stub
		Log.i(TAG, "GPhoneWidget onUpdate called.");
		final int[] Ids = AppWidgetManager
				.getInstance(context)
				.getAppWidgetIds(new ComponentName(context, TogglesWidget.class));

		final RemoteViews views = generateRemoveViews(context);
		initializeViews(context, views);
		appWidgetManager.updateAppWidget(Ids, views);
	}

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		super.onReceive(context, intent);
		RemoteViews views = new RemoteViews(context.getPackageName(),
				R.layout.widget_toggles);

		String action = intent.getAction();
		Log.i(TAG, "received broadcast:" + action);

		if (action.equals(Settings.ACTION_UPDATE_WIDGET)) {
			Log.i(TAG, "process broadcast:" + Settings.ACTION_UPDATE_WIDGET);
			processWidgetSettings(context, intent, views);
		} else if (action.equals(ACTION_AIRPLANE_CHANGED)) {
			Log.i(TAG, "process broadcast:" + action);
			intent.putExtra(IS_CUSTOMIZED, CUSTOMIZED);
			processAirplaneModeEvents(context, intent, views);
		} else if (action.equals(ACTION_SILENT_CHANGED)) {
			Log.i(TAG, "process broadcast:" + action);
			if (intent.getStringExtra("sender").equals("gphone_widget")) {
				processSilentModeEvents(context, views, false);
			} else if (intent.getStringExtra("sender").equals("toogles")) {
				processSilentModeEvents(context, views, false);
			}else {
				processSilentModeEvents(context, views, true);
			}
		} else if (action.equals(ACTION_WIFI_CHANGED)) {
			Log.i(TAG, "process broadcast:" + action);
			intent.putExtra(IS_CUSTOMIZED, CUSTOMIZED);
			processWifiEvents(context, intent, views);
		} else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
			if (intent.getBooleanExtra(MSG_MODE_NO_CHANGE, false)) {
				Log.i(TAG, "broadcast sent from our application, ignore.");
			} else {
				Log.i(TAG, "this broadcast is sent from system.");
				intent.putExtra(IS_CUSTOMIZED, NO_CUSTOMIZED);
				processAirplaneModeEvents(context, intent, views);
			}
		} else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
			if (intent.getBooleanExtra(MSG_MODE_NO_CHANGE, false)) {
				Log.i(TAG, "broadcast sent from our application, ignore.");
			} else {
				Log.i(TAG, "broadcast sent from system, update the widget.");
				intent.putExtra(IS_CUSTOMIZED, NO_CUSTOMIZED);
				processWifiEvents(context, intent, views);
			}
		} else {

		}
	}

	private RemoteViews generateRemoveViews(Context c) {
		RemoteViews views = new RemoteViews(c.getPackageName(),
				R.layout.widget_toggles);

		Intent airplane = new Intent();
		airplane.setAction(ACTION_AIRPLANE_CHANGED);
		PendingIntent airplanePI = PendingIntent
				.getBroadcast(c, 0, airplane, 0);

		Intent brightnessIntent = new Intent(c, AndroidBrightnessControl.class);
		PendingIntent brightnessPendingIntent = PendingIntent.getActivity(c, 0,
				brightnessIntent, 0);

		Intent silent = new Intent();
		silent.setAction(ACTION_SILENT_CHANGED);
		silent.putExtra("sender", "gphone_widget");
		PendingIntent silentPI = PendingIntent.getBroadcast(c, 0, silent, 0);

		Intent wifi = new Intent();
		wifi.setAction(ACTION_WIFI_CHANGED);
		PendingIntent wifiPI = PendingIntent.getBroadcast(c, 0, wifi, 0);


		views.setOnClickPendingIntent(R.id.btnAirplane, airplanePI);
		views.setOnClickPendingIntent(R.id.btnBrightness,
				brightnessPendingIntent);
		views.setOnClickPendingIntent(R.id.btnSilentMode, silentPI);
		views.setOnClickPendingIntent(R.id.btnWifi, wifiPI);
		return views;
	}

	private void initializeViews(Context c, RemoteViews views) {
		ConfigManager manager = ConfigManager.getInstance(c);
		String[] configs = manager.getAllInfos();
		if (!Boolean.valueOf(configs[ConfigManager.AIRPLANE_INDEX])) {
			views.setViewVisibility(R.id.btnAirplane, View.GONE);
		}
		if (!Boolean.valueOf(configs[ConfigManager.BRIGHTNESS_INDEX])) {
			views.setViewVisibility(R.id.btnBrightness, View.GONE);
		}
		if (!Boolean.valueOf(configs[ConfigManager.SILENT_INDEX])) {
			views.setViewVisibility(R.id.btnSilentMode, View.GONE);
		}
		if (!Boolean.valueOf(configs[ConfigManager.WIFI_INDEX])) {
			views.setViewVisibility(R.id.btnWifi, View.GONE);
		}

		boolean airplaneEnabled = System.getInt(c.getContentResolver(),
				System.AIRPLANE_MODE_ON, 0) == 1;
		AudioManager audioManager = (AudioManager) c
				.getSystemService(Context.AUDIO_SERVICE);
		boolean audioEnabled = audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT;
		WifiManager wifiManager = (WifiManager) c
				.getSystemService(Context.WIFI_SERVICE);
		boolean wifiEnabled = wifiManager.isWifiEnabled();
		if (airplaneEnabled) {
			views.setImageViewResource(R.id.btnAirplane, R.drawable.airplane3);
		} else {
			views.setImageViewResource(R.id.btnAirplane, R.drawable.airplane);
		}
		if (audioEnabled) {
			views.setImageViewResource(R.id.btnSilentMode, R.drawable.sound);
		} else {
			views.setImageViewResource(R.id.btnSilentMode, R.drawable.sound3);
		}
		if (wifiEnabled) {
			views.setImageViewResource(R.id.btnWifi, R.drawable.wifi3);
		} else {
			views.setImageViewResource(R.id.btnWifi, R.drawable.wifi);
		}

	}

	/**
	 * If receive events of user customized broadcast, handle it.
	 * 
	 * @param c
	 *            a {@link Context} object
	 * @param intent
	 *            a Intent object which contains data
	 * @param views
	 *            a {@link RemoteViews} object to update
	 */
	private void processWidgetSettings(Context c, Intent intent,
			RemoteViews views) {
		views.setViewVisibility(R.id.btnAirplane, intent.getIntExtra(
				Settings.AIRPLANE_STATUS, 0));
		views.setViewVisibility(R.id.btnBrightness, intent.getIntExtra(
				Settings.BRIGHT_STATUS, 0));
		views.setViewVisibility(R.id.btnSilentMode, intent.getIntExtra(
				Settings.SILENT_MODE_STATUS, 0));
		views.setViewVisibility(R.id.btnWifi, intent.getIntExtra(
				Settings.WIFI_STATUS, 0));
		views.setViewVisibility(R.id.btnFile, intent.getIntExtra(
				Settings.FILE_STATUS, 0));
		views.setViewVisibility(R.id.btnAppList, intent.getIntExtra(
				Settings.APP_LIST_STATUS, 0));
		views.setViewVisibility(R.id.btnAppGrid, intent.getIntExtra(
				Settings.APP_LIST_STATUS, 0));
		views.setViewVisibility(R.id.btnTaskList, intent.getIntExtra(
				Settings.TASK_LIST_STATUS, 0));
		views.setViewVisibility(R.id.btnTaskGrid, intent.getIntExtra(
				Settings.TASK_GRID_STATUS, 0));
		AppWidgetManager m = AppWidgetManager.getInstance(c);
		m.updateAppWidget(new ComponentName(c, TogglesWidget.class), views);
	}

	/**
	 * If receive events of airplane mode changed, handle it.
	 * 
	 * @param context
	 *            a {@link Context} object
	 * @param intent
	 *            a Intent object which contains data
	 * @param views
	 *            a {@link RemoteViews} object to update
	 */
	private void processAirplaneModeEvents(Context c, Intent intent,
			RemoteViews views) {

		boolean enabled = System.getInt(c.getContentResolver(),
				System.AIRPLANE_MODE_ON, 0) == 1;

		if (intent.getBooleanExtra(IS_CUSTOMIZED, false)) {
			Log.i(TAG, "is customized");
			if (enabled) {
				if (System.putInt(c.getContentResolver(),
						System.AIRPLANE_MODE_ON, 0)) {
					views.setImageViewResource(R.id.btnAirplane,
							R.drawable.airplane);
				} else {
					Log.e(TAG, "can not disable airplane mode.");
				}
			} else {
				if (System.putInt(c.getContentResolver(),
						System.AIRPLANE_MODE_ON, 1)) {
					views.setImageViewResource(R.id.btnAirplane,
							R.drawable.airplane3);
				} else {
					Log.e(TAG, "can not enable airplane mode.");
				}
			}
			// send broadcast to tell the system that mode has been changed,
			// but we don't need to update the widget because we already have
			// done this, so we put extra data to distinguish these two
			// broadcasts.
			Intent newIntent = new Intent();
			newIntent.setAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
			newIntent.putExtra(MSG_MODE_NO_CHANGE, NO_CHANGE_VALUE);
			c.sendBroadcast(newIntent);
		} else {
			Log.i(TAG, "is non-customized");
			if (enabled) {
				onAirplaneModeChanged(AirplaneListener.AIRPLANE_TURN_ON, views);
			} else {
				onAirplaneModeChanged(AirplaneListener.AIRPLANE_TURN_OFF, views);
			}
		}
		AppWidgetManager m = AppWidgetManager.getInstance(c);
		m.updateAppWidget(new ComponentName(c, TogglesWidget.class), views);

	}

	/**
	 * To control the silent mode, we use {@link AudioManager}
	 * 
	 * @param c
	 *            a {@link Context} object
	 * @param views
	 *            a {@link RemoteViews} object
	 */
	private void processSilentModeEvents(Context c, RemoteViews views,
			boolean changeSystem) {
		AudioManager audioManager = (AudioManager) c
				.getSystemService(Context.AUDIO_SERVICE);
		int mode = audioManager.getRingerMode();
		if (mode == AudioManager.RINGER_MODE_SILENT) {
			Log.i(TAG, "current audio mode is silent, turning on...");
			if (changeSystem) {
				audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
			}
			views.setImageViewResource(R.id.btnSilentMode, R.drawable.sound3);
		} else {
			Log.i(TAG, "current audio mode is non-silent, turning off...");
			if (changeSystem) {
				audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
			}
			views.setImageViewResource(R.id.btnSilentMode, R.drawable.sound);
		}

		AppWidgetManager m = AppWidgetManager.getInstance(c);
		m.updateAppWidget(new ComponentName(c, TogglesWidget.class), views);
	}

	/**
	 * If receive wifi_mode changed events, handle it
	 * 
	 * @param c
	 *            a {@link Context} object
	 * @param intent
	 *            a Intent object which contains data
	 * @param views
	 *            a {@link RemoteViews} object to update
	 */
	private void processWifiEvents(Context c, Intent intent, RemoteViews views) {
		WifiManager wifiManager = (WifiManager) c
				.getSystemService(Context.WIFI_SERVICE);
		boolean isEnabled = wifiManager.isWifiEnabled();

		if (intent.getBooleanExtra(IS_CUSTOMIZED, false)) {
			Log.i(TAG, "is customized");
			if (isEnabled) {
				wifiManager.setWifiEnabled(false);
				wifiManager.reconnect();
				wifiManager.reassociate();
				views.setImageViewResource(R.id.btnWifi, R.drawable.wifi);
			} else {
				wifiManager.setWifiEnabled(true);
				views.setImageViewResource(R.id.btnWifi, R.drawable.wifi3);
			}
		} else {
			if (isEnabled) {
				onWifiStatusChanged(WIFI_TURN_ON, views);
			} else {
				onWifiStatusChanged(WIFI_TURN_OFF, views);
			}
		}

		AppWidgetManager m = AppWidgetManager.getInstance(c);
		m.updateAppWidget(new ComponentName(c, TogglesWidget.class), views);
	}
}
